home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / Mesa-3.0 / DEMOS / TESSDEMO.C < prev    next >
Encoding:
C/C++ Source or Header  |  1998-07-26  |  8.3 KB  |  417 lines

  1. /* $Id: tessdemo.c,v 3.3 1998/07/26 01:25:26 brianp Exp $ */
  2.  
  3. /*
  4.  * A demo of the GLU polygon tesselation functions written by Bogdan Sikorski.
  5.  * This demo isn't built by the Makefile because it needs GLUT.  After you've
  6.  * installed GLUT you can try this demo.
  7.  * Here's the command for IRIX, for example:
  8.    cc -g -ansi -prototypes -fullwarn -float -I../include -DSHM tess_demo.c -L../lib -lglut -lMesaGLU -lMesaGL -lm -lX11 -lXext -lXmu -lfpe -lXext -o tess_demo
  9.  */
  10.  
  11.  
  12. /*
  13.  * $Log: tessdemo.c,v $
  14.  * Revision 3.3  1998/07/26 01:25:26  brianp
  15.  * removed include of gl.h and glu.h
  16.  *
  17.  * Revision 3.2  1998/06/29 02:37:30  brianp
  18.  * minor changes for Windows (Ted Jump)
  19.  *
  20.  * Revision 3.1  1998/06/09 01:53:49  brianp
  21.  * main() should return an int
  22.  *
  23.  * Revision 3.0  1998/02/14 18:42:29  brianp
  24.  * initial rev
  25.  *
  26.  */
  27.  
  28.  
  29. #include <GL/glut.h>
  30. #include <stdio.h>
  31. #include <stdlib.h>
  32. #include <string.h>
  33.  
  34. #define MAX_POINTS 200
  35. #define MAX_CONTOURS 50
  36.  
  37. int menu;
  38. typedef enum{ QUIT, TESSELATE, CLEAR } menu_entries;
  39. typedef enum{ DEFINE, TESSELATED } mode_type;
  40. struct
  41. {
  42.     GLint p[MAX_POINTS][2];
  43.     GLuint point_cnt;
  44. } contours[MAX_CONTOURS];
  45. GLuint contour_cnt;
  46. GLsizei width,height;
  47. mode_type mode;
  48.  
  49. struct
  50. {
  51.     GLsizei no;
  52.     GLfloat color[3];
  53.     GLint p[3][2];
  54.     GLclampf p_color[3][3];
  55. } triangle;
  56.  
  57. void CALLBACK my_error(GLenum err)
  58. {
  59.     int len,i;
  60.     char const *str;
  61.  
  62.     glColor3f(0.9,0.9,0.9);
  63.     glRasterPos2i(5,5);
  64.     str=(const char *)gluErrorString(err);
  65.     len=strlen(str);
  66.     for(i=0;i<len;i++)
  67.         glutBitmapCharacter(GLUT_BITMAP_9_BY_15,str[i]);
  68. }
  69.  
  70. void CALLBACK begin_callback(GLenum mode)
  71. {
  72.     triangle.no=0;
  73. }
  74.  
  75. void CALLBACK edge_callback(GLenum flag)
  76. {
  77.     if(flag==GL_TRUE)
  78.     {
  79.         triangle.color[0]=1.0;
  80.         triangle.color[1]=1.0;
  81.         triangle.color[2]=0.5;
  82.     }
  83.     else
  84.     {
  85.         triangle.color[0]=1.0;
  86.         triangle.color[1]=0.0;
  87.         triangle.color[2]=0.0;
  88.     }
  89. }
  90.  
  91. void CALLBACK end_callback()
  92. {
  93.     glBegin(GL_LINES);
  94.     glColor3f(triangle.p_color[0][0],triangle.p_color[0][1],
  95.         triangle.p_color[0][2]);
  96.     glVertex2i(triangle.p[0][0],triangle.p[0][1]);
  97.     glVertex2i(triangle.p[1][0],triangle.p[1][1]);
  98.     glColor3f(triangle.p_color[1][0],triangle.p_color[1][1],
  99.         triangle.p_color[1][2]);
  100.     glVertex2i(triangle.p[1][0],triangle.p[1][1]);
  101.     glVertex2i(triangle.p[2][0],triangle.p[2][1]);
  102.     glColor3f(triangle.p_color[2][0],triangle.p_color[2][1],
  103.         triangle.p_color[2][2]);
  104.     glVertex2i(triangle.p[2][0],triangle.p[2][1]);
  105.     glVertex2i(triangle.p[0][0],triangle.p[0][1]);
  106.     glEnd();
  107. }
  108.  
  109. void CALLBACK vertex_callback(void *data)
  110. {
  111.     GLsizei no;
  112.     GLint *p;
  113.  
  114.     p=(GLint *)data;
  115.     no=triangle.no;
  116.     triangle.p[no][0]=p[0];
  117.     triangle.p[no][1]=p[1];
  118.     triangle.p_color[no][0]=triangle.color[0];
  119.     triangle.p_color[no][1]=triangle.color[1];
  120.     triangle.p_color[no][2]=triangle.color[2];
  121.     ++(triangle.no);
  122. }
  123.  
  124. void set_screen_wh(GLsizei w, GLsizei h)
  125. {
  126.     width=w;
  127.     height=h;
  128. }
  129.  
  130. void tesse(void)
  131. {
  132.     GLUtriangulatorObj *tobj;
  133.     GLdouble data[3];
  134.     GLuint i,j,point_cnt;
  135.  
  136.     tobj=gluNewTess();
  137.     if(tobj!=NULL)
  138.     {
  139.         glClear(GL_COLOR_BUFFER_BIT);
  140.         glColor3f (0.7, 0.7, 0.0);
  141.         gluTessCallback(tobj,GLU_BEGIN,glBegin);
  142.         gluTessCallback(tobj,GLU_END,glEnd);
  143.         gluTessCallback(tobj,GLU_ERROR,my_error);
  144.         gluTessCallback(tobj,GLU_VERTEX,glVertex2iv);
  145.         gluBeginPolygon(tobj);
  146.         for(j=0;j<=contour_cnt;j++)
  147.         {
  148.             point_cnt=contours[j].point_cnt;
  149.             gluNextContour(tobj,GLU_UNKNOWN);
  150.             for(i=0;i<point_cnt;i++)
  151.             {
  152.                 data[0]=(GLdouble)(contours[j].p[i][0]);
  153.                 data[1]=(GLdouble)(contours[j].p[i][1]);
  154.                 data[2]=0.0;
  155.                 gluTessVertex(tobj,data,contours[j].p[i]);
  156.             }
  157.         }
  158.         gluEndPolygon(tobj);
  159.         glLineWidth(2.0);
  160.         gluTessCallback(tobj,GLU_BEGIN,begin_callback);
  161.         gluTessCallback(tobj,GLU_END,end_callback);
  162.         gluTessCallback(tobj,GLU_VERTEX,vertex_callback);
  163.         gluTessCallback(tobj,GLU_EDGE_FLAG,edge_callback);
  164.         gluBeginPolygon(tobj);
  165.         for(j=0;j<=contour_cnt;j++)
  166.         {
  167.             point_cnt=contours[j].point_cnt;
  168.             gluNextContour(tobj,GLU_UNKNOWN);
  169.             for(i=0;i<point_cnt;i++)
  170.             {
  171.                 data[0]=(GLdouble)(contours[j].p[i][0]);
  172.                 data[1]=(GLdouble)(contours[j].p[i][1]);
  173.                 data[2]=0.0;
  174.                 gluTessVertex(tobj,data,contours[j].p[i]);
  175.             }
  176.         }
  177.         gluEndPolygon(tobj);
  178.         gluDeleteTess(tobj);
  179.         glutMouseFunc(NULL);
  180.         glColor3f (1.0, 1.0, 0.0);
  181.         glLineWidth(1.0);
  182.         mode=TESSELATED;
  183.     }
  184. }
  185.  
  186. void left_down(int x1,int y1)
  187. {
  188.     GLint P[2];
  189.     GLuint point_cnt;
  190.  
  191.     /* translate GLUT into GL coordinates */
  192.     P[0]=x1;
  193.     P[1]=height-y1;
  194.     point_cnt=contours[contour_cnt].point_cnt;
  195.     contours[contour_cnt].p[point_cnt][0]=P[0];
  196.     contours[contour_cnt].p[point_cnt][1]=P[1];
  197.     glBegin(GL_LINES);
  198.     if(point_cnt)
  199.     {
  200.         glVertex2iv(contours[contour_cnt].p[point_cnt-1]);
  201.         glVertex2iv(P);
  202.     }
  203.     else
  204.     {
  205.         glVertex2iv(P);
  206.         glVertex2iv(P);
  207.     }
  208.     glEnd();
  209.     glFinish();
  210.     ++(contours[contour_cnt].point_cnt);
  211. }
  212.  
  213. void middle_down(int x1,int y1)
  214. {
  215.     GLuint point_cnt;
  216.  
  217.     point_cnt=contours[contour_cnt].point_cnt;
  218.     if(point_cnt>2)
  219.     {
  220.         glBegin(GL_LINES);
  221.         glVertex2iv(contours[contour_cnt].p[0]);
  222.         glVertex2iv(contours[contour_cnt].p[point_cnt-1]);
  223.         contours[contour_cnt].p[point_cnt][0]= -1;
  224.         glEnd();
  225.         glFinish();
  226.         contour_cnt++;
  227.         contours[contour_cnt].point_cnt=0;
  228.     }
  229. }
  230.  
  231. void mouse_clicked(int button,int state,int x,int y)
  232. {
  233.     x-= x%10;
  234.     y-= y%10;
  235.     switch(button)
  236.     {
  237.         case GLUT_LEFT_BUTTON:
  238.             if(state==GLUT_DOWN)
  239.                 left_down(x,y);
  240.             break;
  241.         case GLUT_MIDDLE_BUTTON:
  242.             if(state==GLUT_DOWN)
  243.                 middle_down(x,y);
  244.             break;
  245.     }
  246. }
  247.  
  248. void display(void)
  249. {
  250.     GLuint i,j;
  251.     GLuint point_cnt;
  252.  
  253.     glClear(GL_COLOR_BUFFER_BIT);
  254.     switch(mode)
  255.     {
  256.         case DEFINE:
  257.             /* draw grid */
  258.             glColor3f (0.6,0.5,0.5);
  259.             glBegin(GL_LINES);
  260.             for(i=0;i<width;i+=10)
  261.                 for(j=0;j<height;j+=10)
  262.                 {
  263.                     glVertex2i(0,j);
  264.                     glVertex2i(width,j);
  265.                     glVertex2i(i,height);
  266.                     glVertex2i(i,0);
  267.             }
  268.             glColor3f (1.0, 1.0, 0.0);
  269.             for(i=0;i<=contour_cnt;i++)
  270.             {
  271.                 point_cnt=contours[i].point_cnt;
  272.                 glBegin(GL_LINES);
  273.                 switch(point_cnt)
  274.                 {
  275.                     case 0:
  276.                         break;
  277.                     case 1:
  278.                         glVertex2iv(contours[i].p[0]);
  279.                         glVertex2iv(contours[i].p[0]);
  280.                         break;
  281.                     case 2:
  282.                         glVertex2iv(contours[i].p[0]);
  283.                         glVertex2iv(contours[i].p[1]);
  284.                         break;
  285.                     default:
  286.                         --point_cnt;
  287.                         for(j=0;j<point_cnt;j++)
  288.                         {
  289.                             glVertex2iv(contours[i].p[j]);
  290.                             glVertex2iv(contours[i].p[j+1]);
  291.                         }
  292.                         if(contours[i].p[j+1][0]== -1)
  293.                         {
  294.                             glVertex2iv(contours[i].p[0]);
  295.                             glVertex2iv(contours[i].p[j]);
  296.                         }
  297.                         break;
  298.                 }
  299.                 glEnd();
  300.             }
  301.             glFinish();
  302.             break;
  303.         case TESSELATED:
  304.             /* draw lines */
  305.             tesse();
  306.             break;
  307.     }
  308.  
  309.     glColor3f (1.0, 1.0, 0.0);
  310. }
  311.  
  312. void clear( void )
  313. {
  314.     contour_cnt=0;
  315.     contours[0].point_cnt=0;
  316.     glutMouseFunc(mouse_clicked);
  317.     mode=DEFINE;
  318.     display();
  319. }
  320.  
  321. void quit( void )
  322. {
  323.     exit(0);
  324. }
  325.  
  326. void menu_selected(int entry)
  327. {
  328.     switch(entry)
  329.     {
  330.         case CLEAR:
  331.             clear();
  332.             break;
  333.         case TESSELATE:
  334.             tesse();
  335.             break;
  336.         case QUIT:
  337.             quit();
  338.             break;
  339.     }
  340. }
  341.  
  342. void key_pressed(unsigned char key,int x,int y)
  343. {
  344.     switch(key)
  345.     {
  346.         case 't':
  347.         case 'T':
  348.             tesse();
  349.             glFinish();
  350.             break;
  351.         case 'q':
  352.         case 'Q':
  353.             quit();
  354.             break;
  355.         case 'c':
  356.         case 'C':
  357.             clear();
  358.             break;
  359.     }
  360. }
  361.  
  362. void myinit (void) 
  363. {
  364. /*  clear background to gray    */
  365.     glClearColor (0.4, 0.4, 0.4, 0.0);
  366.     glShadeModel (GL_FLAT);    
  367.  
  368.     menu=glutCreateMenu(menu_selected);
  369.     glutAddMenuEntry("clear",CLEAR);
  370.     glutAddMenuEntry("tesselate",TESSELATE);
  371.     glutAddMenuEntry("quit",QUIT);
  372.     glutAttachMenu(GLUT_RIGHT_BUTTON);
  373.     glutMouseFunc(mouse_clicked);
  374.     glutKeyboardFunc(key_pressed);
  375.     contour_cnt=0;
  376.     glPolygonMode(GL_FRONT,GL_FILL);
  377.     mode=DEFINE;
  378. }
  379.  
  380. static void reshape(GLsizei w, GLsizei h)
  381. {
  382.     glViewport(0, 0, w, h);
  383.     glMatrixMode(GL_PROJECTION);
  384.     glLoadIdentity();
  385.     glOrtho(0.0, (GLdouble)w, 0.0, (GLdouble)h, -1.0, 1.0);
  386.     glMatrixMode(GL_MODELVIEW);
  387.     glLoadIdentity();
  388.     set_screen_wh(w,h);
  389. }
  390.  
  391.  
  392. static void usage( void )
  393. {
  394.    printf("Use left mouse button to place vertices.\n");
  395.    printf("Press middle mouse button when done.\n");
  396.    printf("Select tesselate from the pop-up menu.\n");
  397. }
  398.  
  399.  
  400. /*  Main Loop
  401.  *  Open window with initial window size, title bar, 
  402.  *  RGBA display mode, and handle input events.
  403.  */
  404. int main(int argc, char** argv)
  405. {
  406.    usage();
  407.    glutInit(&argc, argv);
  408.    glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
  409.    glutInitWindowSize (400, 400);
  410.    glutCreateWindow (argv[0]);
  411.    myinit ();
  412.    glutDisplayFunc(display);
  413.    glutReshapeFunc(reshape);
  414.    glutMainLoop();
  415.    return 0;
  416. }
  417.